﻿using System;
using Aeon.Framework;
using Tao.Platform.Windows;
using System.Windows.Forms;
using Aeon.Framework.Objects;
using Aeon.Testing.Properties;

namespace Aeon.Testing
{

public partial class WindowBuild : Form
    {
    // --- Attributes: 

    private String Console
        {
        set {
            BoxConsole.Text += value + "\r\n"; 

            BoxConsole.SelectionStart = BoxConsole.TextLength;
            BoxConsole.ScrollToCaret();
            }
        }

    private SimpleOpenGlControl Display;
    private Boolean running;
    private World world;

    // --- Constructor:

    public WindowBuild()
        {        
        InitializeComponent();
        Icon = Resources.AeonIco;
        
        world = null;
        Display = null;
        running = false;
        
        enablePanels(false);

        Console = " *** Framework ready.";
        }

    // --- Private Methods:

    #region Top Level

    // Component Handlers
    
    private void WindowBuild_FormClosing(Object sender,FormClosingEventArgs e)
        {
        
        if (running) stopManaged();
        }

    private void ButtonExit_Click(Object sender, System.EventArgs e)
        {

        this.Close();
        }

    private void ButtonClear_Click(Object sender, EventArgs e)
        {

        BoxConsole.Text = String.Empty;
        Console = " *** Console cleared.";
        }

    private void ButtonInvalidate_Click(Object sender, EventArgs e)
        {

        updateScreen();
        }
    
    private void SizeHandler(Object obj, EventArgs arg)
        {
        Control window = obj as Control;

        if (world!=null ) world.SetCamera(window.Height,window.Width);
        // To prevent mysterious Invoke on event assignment when world is still null.
        }
  
    private void RenderHandler(Object obj, PaintEventArgs arg)
        {

        world.RenderScene();
        }

    // Methods

    private void updateScreen()
        {

        if (Display!=null) Display.Invalidate(true);
        }

    private void enablePanels(bool enable)
        {
        PanelAnimation.Enabled = enable;
        PanelTexture.Enabled = enable;
        PanelCamera.Enabled = enable;
        PanelWorld.Enabled = enable;
        PanelSound.Enabled = enable;
        PanelText.Enabled = enable;
        }

    #endregion

    #region AEON Settings

    // Component Handlers

    private void RadioOff_CheckedChanged(object sender, EventArgs e)
        {

        if (RadioOff.Checked) { stopManaged(); ButtonReset.Enabled = false; }
        }

    private void RadioOn_CheckedChanged(object sender, EventArgs e)
        {

        if (RadioOn.Checked) { startManaged(); ButtonReset.Enabled = true; }
        }

    private void ButtonReset_Click(object sender, EventArgs e)
        {
        if (running)
           {           
           stopManaged();
           startManaged();
           }
        }

    // Methods
    
    /// <summary>
    /// Necessary steps to start the AEON:      // [TODO] Update.
    /// 
    ///     1 - Create OpenGl display Control.
    ///     2 - Bind Control's OnPaint event to World RendeScene.
    ///     3 - Bind any other input events.
    ///     4 - Initialize Control Context.
    ///     5 - Create World.
    ///     6 - Set World camera position and orientation.
    ///     7 - Add World content: actors, lights, sounds.
    ///     8 - Enjoy!
    ///     
    /// Note: An active OpenGL Control Context is necessary for the
    ///       creation of a World. A World will then use the last
    ///       initialized Context as its own. That World is bound to
    ///       that Context. Independent N-Worlds will need N-Contexts,
    ///       all initialized in the correct order. Worlds that share
    ///       their bindings will have the same content while having
    ///       acces only to its own subset of that content.
    /// 
    /// </summary>
    private void startManaged()
        {
        Console = " *** Starting AEON.";

        Display = new SimpleOpenGlControl();
        PanelDisplay.Controls.Add(Display);
        Display.Paint += RenderHandler;
        Display.Resize += SizeHandler;
        Display.Dock = DockStyle.Fill;
        Display.InitializeContexts();
        Console = " *** Display OK.";

        running = true;
        enablePanels(true);

        WorldCreate();
        Console = " *** Scene OK.";

        WorldLights();
        Console = " *** Lights OK.";

        // Animation Timer
        // Texture Manager
        // Sound System
        
        Console = " *** AEON initialized.";
        }

    /// <summary>
    /// Desirable steps to stop the AEON:   // [TODO] Update.
    /// 
    ///     1 - Call World DestroyScene.
    ///     2 - Destroy Context associated with that World.
    ///     3 - That's it, no leaks.
    ///     
    /// Note: The Font Manager and the Texture Manager share some of
    ///       the same textures. Their Clean methods can be called
    ///       separately, however don'k call one while the other is
    ///       still being used or there can be missing resources.
    /// 
    /// </summary>
    private void stopManaged()
        {        
        Console = " *** Stopping AEON...";
        
        WorldClean();

        PanelDisplay.Controls.Clear();
        Display.DestroyContexts();
        Display.Invalidate();
        
        world = null;
        running = false;
        enablePanels(false);

        Console = " *** AEON stopped.";
        }

    #endregion

    #region Scene Editor

    // Component Handlers
    
    private void ButtonWorldAdd_Click(object sender, EventArgs e)
        {
        WorldAddLast();
        WorldStateControl();
        
        BoxWorldNewId.Text = String.Empty;        
        updateScreen();
        }

    private void ButtonWorldRemoveId_Click(object sender, EventArgs e)
        {
        WorldRemoveId(BoxWorldRemoveId.Text);
        WorldStateControl();

        BoxWorldRemoveId.Text = String.Empty;
        updateScreen();        
        }

    private void ButtonWorldRemoveAll_Click(object sender, EventArgs e)
        {
        WorldClean();
        WorldStateControl();

        updateScreen();
        }

    private void ButtonWorldRemoveLast_Click(object sender, EventArgs e)
        {
        WorldRemoveLast();
        WorldStateControl();

        updateScreen();
        }

    private void RadioWorldNewTriangle_CheckedChanged(object sender, EventArgs e)
        {
        if (RadioWorldNewTriangle.Checked) { selection = "Triangle"; createTriangleOptions(); }
        }

    private void RadioWorldNewCross_CheckedChanged(object sender, EventArgs e)
        {
        if (RadioWorldNewCross.Checked) { selection = "Cross"; createCrossOptions(); }
        }

    private void RadioWorldNewSphere_CheckedChanged(object sender, EventArgs e)
        {
        if (RadioWorldNewSphere.Checked) { selection = "Sphere"; createSphereOptions(); }
        }
        
    private void RadioWorldNewPlane_CheckedChanged(object sender,EventArgs e)
        {
        if (RadioWorldNewPlane.Checked) { selection = "Plane"; createPlaneOptions(); }
        }

    private void RadioWorldNewLine_CheckedChanged(object sender, EventArgs e)
        {
        if (RadioWorldNewLine.Checked) { selection = "Line"; createLineOptions(); }
        }

    // Methods

    private short listHeight = 0;
    private string selection = String.Empty;

    private void WorldStateControl()
        {
        bool status;

        if (BoxActorsList.Controls.Count == 0) status = false;
        else status = true;

        BoxWorldRemoveId.Enabled = status;
        ButtonWorldRemoveId.Enabled = status;
        ButtonWorldRemoveAll.Enabled = status;
        ButtonWorldRemoveLast.Enabled = status;
        }

    private void WorldLights()
        {
        AeonColor amb = new AeonColor(0.2f,0.2f,0.2f,1.0f);
        AeonColor dif = new AeonColor(0.8f,0.8f,0.8f,1.0f);
        AeonColor spc = new AeonColor(1.0f,1.0f,1.0f,1.0f);
        Position pos = new Position(0.0f,50.0f,50.0f);

        AeonLight lgt = new AeonLight("Main Light",pos,amb,dif,spc);
        world.Add(lgt);
        
        Console = " * Added light with ID " + "Main Light" + ".";
        
        // [TODO] Integrate with BoxWorldList visualization.
        }

    private void WorldCreate()
        {
        WorldManager.SetModules(typeof(AeonTextureManager),typeof(AeonFontManager),typeof(MockAudioManager),typeof(MockInputManager),typeof(MockPhysicsManager));
        
        AeonColors.Default = AeonColors.Black;
        world = WorldManager.CreateWorld("AEON Builder");

        cameraSeed();
        
        WorldStateControl();
        }

    private void WorldClean()
        {
        for (Int32 all = BoxActorsList.Controls.Count; all>0; all--) WorldRemoveLast();

        BoxActorsList.Controls.Clear();
        listHeight = 0;
        
        world.DestroyScene();
        AeonColors.Default = AeonColors.White;
        
        Console = " * Removed all world objects.";
        }

    private void WorldRemoveLast()
        {
        Int32 last = BoxActorsList.Controls.Count-1;
        String key = (BoxActorsList.Controls[last] as Button).Text;

        WorldRemoveId(key);
        }

    private void WorldRemoveId(String key)
        {
        bool found = false;
        Button forRemoval = null;

        foreach(Button button in BoxActorsList.Controls)
            {
            if (button.Text == key)
               {
               if (world.Remove(key))
                  {                  
                  Console = " * Removed actor with ID "+key+".";

                  forRemoval = button;
                  listHeight -= 34;
                  found = true;
                  }               
               }
            
            else { if (found) { button.Top -= 34; } }
            }
            
        if (found) { BoxActorsList.Controls.Remove(forRemoval); }
        else { Console = " * Cannot remove object. Not found."; }
        }

    private void WorldAddLast()
        {
        IKey obj = validateCreation();

        if (obj != null)
            {
            Button item = new Button();
            item.Top = listHeight + 9;
            item.Enabled = false;
            item.Text = obj.ID;
            item.Height = 25;
            item.Width = 75;
            item.Left = 15;

            if (world.Add(obj))
               {
               BoxActorsList.Controls.Add(item);
               Console = " * Added actor with ID "+obj.ID+".";

               listHeight += 34;
               }

            else { Console = " * Cannot add actor. Duplicate ID."; }
            }
        }

    private IKey validateCreation()
        {
        IKey obj = null;

        try {
            if (BoxWorldNewId.Text == String.Empty || selection == String.Empty ||
                BoxWorldNewAX.Text == String.Empty || BoxWorldNewCX.Text == String.Empty ||
                BoxWorldNewAY.Text == String.Empty || BoxWorldNewCY.Text == String.Empty ||
                BoxWorldNewAZ.Text == String.Empty || BoxWorldNewCZ.Text == String.Empty )
                throw new ArgumentNullException();

            switch(selection)
                {
                case "Line": if ((obj = validateLine()) == null) throw new ArgumentException(); break;
                case "Plane": if ((obj = validatePlane()) == null) throw new ArgumentNullException(); break;
                case "Cross": if ((obj = validateCross()) == null) throw new ArgumentNullException(); break;
                case "Sphere": if ((obj = validateSphere()) == null) throw new ArgumentNullException(); break;
                case "Triangle": if ((obj = validateTriangle()) == null) throw new ArgumentNullException(); break;
                }
            }

        catch { Console = " * Input error. Object not created."; }

        return(obj);
        }

    private void createCrossOptions()
        {
        PanelWorldParameters.Controls.Clear();

        Label labelSize = new Label();      
        labelSize.Text = "Size: ";          
        labelSize.Width = 30;               
        labelSize.Left = 10;                
        labelSize.Top = 10;                 

        TextBox boxSize = new TextBox();
        boxSize.Name = "BoxTSize";
        boxSize.Width = 35;
        boxSize.Left = 45;
        boxSize.Top = 5;

        PanelWorldParameters.Controls.Add(boxSize);
        PanelWorldParameters.Controls.Add(labelSize);
        }

    private Cross validateCross()
        {
        Cross cross;

        try {
            String id = BoxWorldNewId.Text;
            Single cx = Convert.ToSingle(BoxWorldNewCX.Text);
            Single cy = Convert.ToSingle(BoxWorldNewCY.Text);
            Single cz = Convert.ToSingle(BoxWorldNewCZ.Text);
            Single ax = Convert.ToSingle(BoxWorldNewAX.Text);
            Single ay = Convert.ToSingle(BoxWorldNewAY.Text);
            Single az = Convert.ToSingle(BoxWorldNewAZ.Text);

            TextBox boxSize = PanelWorldParameters.Controls.Find("BoxTSize",true)[0] as TextBox;            
            Single size = Convert.ToSingle(boxSize.Text);

            cross = new Cross(id,new Position(cx,cy,cz),new Framework.Orientation(ax,ay,az),size);
            cross.Material.Color = new AeonColorMany(AeonColors.Red,AeonColors.Green,AeonColors.Blue);
            }

        catch { cross = null; }

        return(cross);
        }

    private void createTriangleOptions()
        {
        PanelWorldParameters.Controls.Clear();

        Label labelSize = new Label();      TextBox boxSize = new TextBox();    Label labelColor = new Label();
        labelSize.Text = "Size: ";          boxSize.Name = "BoxTSize";          labelColor.Text = "Color: ";
        labelSize.Width = 30;               boxSize.Width = 35;                 labelColor.Width = 40;
        labelSize.Left = 10;                boxSize.Left = 45;                  labelColor.Left = 10;
        labelSize.Top = 10;                 boxSize.Top = 5;                    labelColor.Top = 50;

        Label labelCR = new Label();        Label labelCG = new Label();        Label labelCB = new Label();
        labelCR.Text = "R";                 labelCG.Text = "G";                 labelCB.Text = "B";
        labelCR.Width = 15;                 labelCG.Width = 15;                 labelCB.Width = 15;
        labelCR.Left = 55;                  labelCG.Left = 95;                  labelCB.Left = 135;
        labelCR.Top = 30;                   labelCG.Top = 30;                   labelCB.Top = 30;
        
        TextBox boxColorR = new TextBox();  TextBox boxColorG = new TextBox();  TextBox boxColorB = new TextBox(); 
        boxColorR.Name = "BoxTColorR";      boxColorG.Name = "BoxTColorG";      boxColorB.Name = "BoxTColorB";
        boxColorR.Width = 35;               boxColorG.Width = 35;               boxColorB.Width = 35;
        boxColorR.Left = 45;                boxColorG.Left = 85;                boxColorB.Left = 125;
        boxColorR.Top = 45;                 boxColorG.Top = 45;                 boxColorB.Top = 45;

        PanelWorldParameters.Controls.Add(labelSize);
        PanelWorldParameters.Controls.Add(boxSize);
        PanelWorldParameters.Controls.Add(boxColorR);
        PanelWorldParameters.Controls.Add(boxColorG);
        PanelWorldParameters.Controls.Add(boxColorB);
        PanelWorldParameters.Controls.Add(labelColor);
        PanelWorldParameters.Controls.Add(labelCR);
        PanelWorldParameters.Controls.Add(labelCG);
        PanelWorldParameters.Controls.Add(labelCB);
        }

    private Triangle validateTriangle()
        {
        Triangle triangle;

        try {
            String id = BoxWorldNewId.Text;
            Single cx = Convert.ToSingle(BoxWorldNewCX.Text);
            Single cy = Convert.ToSingle(BoxWorldNewCY.Text);
            Single cz = Convert.ToSingle(BoxWorldNewCZ.Text);
            Single ax = Convert.ToSingle(BoxWorldNewAX.Text);
            Single ay = Convert.ToSingle(BoxWorldNewAY.Text);
            Single az = Convert.ToSingle(BoxWorldNewAZ.Text);

            TextBox boxSize = PanelWorldParameters.Controls.Find("BoxTSize",true)[0] as TextBox;
            TextBox boxR = PanelWorldParameters.Controls.Find("BoxTColorR",true)[0] as TextBox;
            TextBox boxG = PanelWorldParameters.Controls.Find("BoxTColorG",true)[0] as TextBox;
            TextBox boxB = PanelWorldParameters.Controls.Find("BoxTColorB",true)[0] as TextBox;
            
            Single size = Convert.ToSingle(boxSize.Text);
            Single r = Convert.ToSingle(boxR.Text);
            Single g = Convert.ToSingle(boxG.Text);
            Single b = Convert.ToSingle(boxB.Text);

            triangle = new Triangle(id,new Position(cx,cy,cz),new Framework.Orientation(ax,ay,az),size);
            triangle.Material.Color = new AeonColor(r,g,b);
            }
        
        catch { triangle = null; }

        return(triangle);
        }

    private void createSphereOptions()
        {
        PanelWorldParameters.Controls.Clear();

        Label labelSize = new Label();      TextBox boxSize = new TextBox();    Label labelColor = new Label();
        labelSize.Text = "Radius: ";        boxSize.Name = "BoxSSize";          labelColor.Text = "Color: ";
        labelSize.Width = 45;               boxSize.Width = 35;                 labelColor.Width = 40;
        labelSize.Left = 10;                boxSize.Left = 55;                  labelColor.Left = 10;
        labelSize.Top = 10;                 boxSize.Top = 5;                    labelColor.Top = 50;

        Label labelCR = new Label();        Label labelCG = new Label();        Label labelCB = new Label();
        labelCR.Text = "R";                 labelCG.Text = "G";                 labelCB.Text = "B";
        labelCR.Width = 15;                 labelCG.Width = 15;                 labelCB.Width = 15;
        labelCR.Left = 55;                  labelCG.Left = 95;                  labelCB.Left = 135;
        labelCR.Top = 30;                   labelCG.Top = 30;                   labelCB.Top = 30;
        
        TextBox boxColorR = new TextBox();  TextBox boxColorG = new TextBox();  TextBox boxColorB = new TextBox(); 
        boxColorR.Name = "BoxSColorR";      boxColorG.Name = "BoxSColorG";      boxColorB.Name = "BoxSColorB";
        boxColorR.Width = 35;               boxColorG.Width = 35;               boxColorB.Width = 35;
        boxColorR.Left = 45;                boxColorG.Left = 85;                boxColorB.Left = 125;
        boxColorR.Top = 45;                 boxColorG.Top = 45;                 boxColorB.Top = 45;

        PanelWorldParameters.Controls.Add(labelSize);
        PanelWorldParameters.Controls.Add(boxSize);
        PanelWorldParameters.Controls.Add(boxColorR);
        PanelWorldParameters.Controls.Add(boxColorG);
        PanelWorldParameters.Controls.Add(boxColorB);
        PanelWorldParameters.Controls.Add(labelColor);
        PanelWorldParameters.Controls.Add(labelCR);
        PanelWorldParameters.Controls.Add(labelCG);
        PanelWorldParameters.Controls.Add(labelCB);
        }

    private Sphere validateSphere()
        {
        Sphere sphere;

        try {
            String id = BoxWorldNewId.Text;
            Single cx = Convert.ToSingle(BoxWorldNewCX.Text);
            Single cy = Convert.ToSingle(BoxWorldNewCY.Text);
            Single cz = Convert.ToSingle(BoxWorldNewCZ.Text);
            Single ax = Convert.ToSingle(BoxWorldNewAX.Text);
            Single ay = Convert.ToSingle(BoxWorldNewAY.Text);
            Single az = Convert.ToSingle(BoxWorldNewAZ.Text);

            TextBox boxRad = PanelWorldParameters.Controls.Find("BoxSSize",true)[0] as TextBox;
            TextBox boxR = PanelWorldParameters.Controls.Find("BoxSColorR",true)[0] as TextBox;
            TextBox boxG = PanelWorldParameters.Controls.Find("BoxSColorG",true)[0] as TextBox;
            TextBox boxB = PanelWorldParameters.Controls.Find("BoxSColorB",true)[0] as TextBox;
            
            Single radius = Convert.ToSingle(boxRad.Text);
            Single r = Convert.ToSingle(boxR.Text);
            Single g = Convert.ToSingle(boxG.Text);
            Single b = Convert.ToSingle(boxB.Text);

            sphere = new Sphere(id,new Position(cx,cy,cz),new Framework.Orientation(ax,ay,az),radius);
            sphere.Material.Color = new AeonColor(r,g,b);
            }

        catch { sphere = null; }

        return(sphere);
        }
        
    private void createPlaneOptions()
        {
        PanelWorldParameters.Controls.Clear();
        
        Label labelWidth = new Label();     TextBox boxWidth = new TextBox();
        labelWidth.Text = "Width:";         boxWidth.Name = "BoxPWidth";
        labelWidth.Width = 40;              boxWidth.Width = 35;
        labelWidth.Left = 10;               boxWidth.Left = 50;
        labelWidth.Top = 8;                 boxWidth.Top = 4;
        
        Label labelDepth = new Label();     TextBox boxDepth = new TextBox();
        labelDepth.Text = "Depth:";         boxDepth.Name = "BoxPDepth";
        labelDepth.Width = 40;              boxDepth.Width = 35;
        labelDepth.Left = 95;               boxDepth.Left = 135;
        labelDepth.Top = 8;                 boxDepth.Top = 4;
        
        Label labelColor = new Label();
        labelColor.Text = "Color: ";
        labelColor.Width = 40;
        labelColor.Left = 10;
        labelColor.Top = 50;
        
        Label labelCR = new Label();        Label labelCG = new Label();        Label labelCB = new Label();
        labelCR.Text = "R";                 labelCG.Text = "G";                 labelCB.Text = "B";
        labelCR.Width = 15;                 labelCG.Width = 15;                 labelCB.Width = 15;
        labelCR.Left = 55;                  labelCG.Left = 95;                  labelCB.Left = 135;
        labelCR.Top = 30;                   labelCG.Top = 30;                   labelCB.Top = 30;
        
        TextBox boxColorR = new TextBox();  TextBox boxColorG = new TextBox();  TextBox boxColorB = new TextBox(); 
        boxColorR.Name = "BoxPColorR";      boxColorG.Name = "BoxPColorG";      boxColorB.Name = "BoxPColorB";
        boxColorR.Width = 35;               boxColorG.Width = 35;               boxColorB.Width = 35;
        boxColorR.Left = 45;                boxColorG.Left = 85;                boxColorB.Left = 125;
        boxColorR.Top = 45;                 boxColorG.Top = 45;                 boxColorB.Top = 45;
        
        PanelWorldParameters.Controls.Add(labelWidth);
        PanelWorldParameters.Controls.Add(boxWidth);
        PanelWorldParameters.Controls.Add(labelDepth);
        PanelWorldParameters.Controls.Add(boxDepth);
        PanelWorldParameters.Controls.Add(boxColorR);
        PanelWorldParameters.Controls.Add(boxColorG);
        PanelWorldParameters.Controls.Add(boxColorB);
        PanelWorldParameters.Controls.Add(labelColor);
        PanelWorldParameters.Controls.Add(labelCR);
        PanelWorldParameters.Controls.Add(labelCG);
        PanelWorldParameters.Controls.Add(labelCB);
        }

    private Plane validatePlane()
        {
        Plane plane;
        
        try {
            String id = BoxWorldNewId.Text;
            Single cx = Convert.ToSingle(BoxWorldNewCX.Text);
            Single cy = Convert.ToSingle(BoxWorldNewCY.Text);
            Single cz = Convert.ToSingle(BoxWorldNewCZ.Text);
            Single ax = Convert.ToSingle(BoxWorldNewAX.Text);
            Single ay = Convert.ToSingle(BoxWorldNewAY.Text);
            Single az = Convert.ToSingle(BoxWorldNewAZ.Text);

            TextBox boxX = PanelWorldParameters.Controls.Find("BoxPWidth",true)[0] as TextBox;
            TextBox boxZ = PanelWorldParameters.Controls.Find("BoxPDepth",true)[0] as TextBox;            
            TextBox boxR = PanelWorldParameters.Controls.Find("BoxPColorR",true)[0] as TextBox;
            TextBox boxG = PanelWorldParameters.Controls.Find("BoxPColorG",true)[0] as TextBox;
            TextBox boxB = PanelWorldParameters.Controls.Find("BoxPColorB",true)[0] as TextBox;
            
            Single x = Convert.ToSingle(boxX.Text);
            Single z = Convert.ToSingle(boxZ.Text);
            Single r = Convert.ToSingle(boxR.Text);
            Single g = Convert.ToSingle(boxG.Text);
            Single b = Convert.ToSingle(boxB.Text);
            
            plane = new Plane(id,new Position(cx,cy,cz),new Framework.Orientation(ax,ay,az),x,z,AeonMaterials.Default);
            plane.Material.Color = new AeonColor(r,g,b);
            }
            
        catch { plane = null; }
        
        return(plane);
        }

    private void createLineOptions()
        {
        PanelWorldParameters.Controls.Clear();
        
        Label labelLength = new Label();    TextBox boxLength = new TextBox();
        labelLength.Text = "Length:";       boxLength.Name = "BoxLLength";
        labelLength.Width = 45;             boxLength.Width = 35;
        labelLength.Left = 10;              boxLength.Left = 55;
        labelLength.Top = 8;                boxLength.Top = 4;
        
        Label labelColor = new Label();
        labelColor.Text = "Color: ";
        labelColor.Width = 40;
        labelColor.Left = 10;
        labelColor.Top = 50;
        
        Label labelCR = new Label();        Label labelCG = new Label();        Label labelCB = new Label();
        labelCR.Text = "R";                 labelCG.Text = "G";                 labelCB.Text = "B";
        labelCR.Width = 15;                 labelCG.Width = 15;                 labelCB.Width = 15;
        labelCR.Left = 55;                  labelCG.Left = 95;                  labelCB.Left = 135;
        labelCR.Top = 30;                   labelCG.Top = 30;                   labelCB.Top = 30;
        
        TextBox boxColorR = new TextBox();  TextBox boxColorG = new TextBox();  TextBox boxColorB = new TextBox(); 
        boxColorR.Name = "BoxLColorR";      boxColorG.Name = "BoxLColorG";      boxColorB.Name = "BoxLColorB";
        boxColorR.Width = 35;               boxColorG.Width = 35;               boxColorB.Width = 35;
        boxColorR.Left = 45;                boxColorG.Left = 85;                boxColorB.Left = 125;
        boxColorR.Top = 45;                 boxColorG.Top = 45;                 boxColorB.Top = 45;
        
        PanelWorldParameters.Controls.Add(labelLength);
        PanelWorldParameters.Controls.Add(boxLength);
        PanelWorldParameters.Controls.Add(boxColorR);
        PanelWorldParameters.Controls.Add(boxColorG);
        PanelWorldParameters.Controls.Add(boxColorB);
        PanelWorldParameters.Controls.Add(labelColor);
        PanelWorldParameters.Controls.Add(labelCR);
        PanelWorldParameters.Controls.Add(labelCG);
        PanelWorldParameters.Controls.Add(labelCB);
        }

    private Line validateLine()
        {
        Line line;
    
        try {
            String id = BoxWorldNewId.Text;
            Single cx = Convert.ToSingle(BoxWorldNewCX.Text);
            Single cy = Convert.ToSingle(BoxWorldNewCY.Text);
            Single cz = Convert.ToSingle(BoxWorldNewCZ.Text);
            Single ax = Convert.ToSingle(BoxWorldNewAX.Text);
            Single ay = Convert.ToSingle(BoxWorldNewAY.Text);
            Single az = Convert.ToSingle(BoxWorldNewAZ.Text);

            TextBox boxL = PanelWorldParameters.Controls.Find("BoxLLength",true)[0] as TextBox;            
            TextBox boxR = PanelWorldParameters.Controls.Find("BoxLColorR",true)[0] as TextBox;
            TextBox boxG = PanelWorldParameters.Controls.Find("BoxLColorG",true)[0] as TextBox;
            TextBox boxB = PanelWorldParameters.Controls.Find("BoxLColorB",true)[0] as TextBox;
            
            Single l = Convert.ToSingle(boxL.Text);
            Single r = Convert.ToSingle(boxR.Text);
            Single g = Convert.ToSingle(boxG.Text);
            Single b = Convert.ToSingle(boxB.Text);

            line = new Line(id,new Position(cx,cy,cz),new Framework.Orientation(ax,ay,az),l);
            line.Material.Color = new AeonColor(r,g,b);
            }

        catch { line = null; }
        
        return(line);
        }

    #endregion

    #region Camera Editor

    // Component Handlers

    private void ButtonCameraReset_Click(object sender, EventArgs e)
        {
        cameraSeed();
        
        updateScreen();
        }

    private void ButtonCameraWindow_Click(object sender, EventArgs e)
        {
        cameraViewport();
        
        updateScreen();
        }
        
    private void ButtonCameraMove_Click(object sender,EventArgs e)
        {        
        cameraMove();
        
        updateScreen();
        }
        
    private void RadioCameraMoveAbsolute_CheckedChanged(object sender,EventArgs e)
        {
        
        if (RadioCameraMoveAbsolute.Checked) LabelCameraMoveTo.Text = "To";
        }

    private void RadioCameraMoveRelative_CheckedChanged(object sender,EventArgs e)
        {

        if (RadioCameraMoveRelative.Checked) LabelCameraMoveTo.Text = "By";
        }
        
    private void ButtonCameraTurn_Click(object sender,EventArgs e)
        {
        cameraTurn();
        
        updateScreen();
        }
        
    private void RadioCameraTurnAbsolute_CheckedChanged(object sender,EventArgs e)
        {
        
        if (RadioCameraTurnAbsolute.Checked) LabelCameraTurnTo.Text = "To";
        }

    private void RadioCameraTurnRelative_CheckedChanged(object sender,EventArgs e)
        {

        if (RadioCameraTurnRelative.Checked) LabelCameraTurnTo.Text = "By";
        }

    // Methods

    private void cameraSeed()
        {        
        BoxCameraWindowV.Text = Display.Height.ToString();
        BoxCameraWindowH.Text = Display.Width.ToString();
        
        RadioCameraMoveAbsolute.Checked = true;
        BoxCameraMoveX.Text = "0";
        BoxCameraMoveY.Text = "0";
        BoxCameraMoveZ.Text = "300";
        
        RadioCameraTurnAbsolute.Checked = true;
        BoxCameraTurnX.Text = "-20";
        BoxCameraTurnY.Text = "15";
        BoxCameraTurnZ.Text = "0";
        
        cameraViewport();
        cameraMove();
        cameraTurn();
        }
        
    private void cameraViewport()
        {
        try {
            int height = Convert.ToInt32(BoxCameraWindowV.Text);
            int width = Convert.ToInt32(BoxCameraWindowH.Text);

            world.SetCamera(height,width);
            Console = " * Camera viewport set.";
            }

        catch { Console = " * Input Error. Incorrect distances."; }    
        }
        
    private void cameraMove()
        {
        try {
            Single x = Convert.ToSingle(BoxCameraMoveX.Text);
            Single y = Convert.ToSingle(BoxCameraMoveY.Text);
            Single z = Convert.ToSingle(BoxCameraMoveZ.Text);
            
            if (RadioCameraMoveAbsolute.Checked || RadioCameraMoveRelative.Checked)
               {
               if (RadioCameraMoveAbsolute.Checked) { world.CameraMoveTo(new Position(x,y,z)); }
               if (RadioCameraMoveRelative.Checked) { world.CameraMoveBy(new VectorC(x,y,z)); }
               
               Console = " * Camera movement succesful.";
               }
               
            else { Console = " * Input error. Choose absolute or relative coordinates.";  }
            }
        
        catch { Console = " * Input error. Incorrect coordinates."; }
        }
        
    private void cameraTurn()
        {
        try {
            Single x = Convert.ToSingle(BoxCameraTurnX.Text);
            Single y = Convert.ToSingle(BoxCameraTurnY.Text);
            Single z = Convert.ToSingle(BoxCameraTurnZ.Text);
            
            if (RadioCameraMoveAbsolute.Checked || RadioCameraMoveRelative.Checked)
               {
               if (RadioCameraTurnAbsolute.Checked) { world.CameraTurnTo(new Framework.Orientation(x,y,z)); }
               if (RadioCameraTurnRelative.Checked) { world.CameraTurnBy(new Framework.Orientation(x,y,z)); }
               
               Console = " * Camera rotation succesful.";
               }
               
            else { Console = " * Input error. Choose absolute or relative angles.";  }
            }
        
        catch { Console = " * Input error. Incorrect angles."; }
        }
        
    #endregion

    #region Animation Editor

    // Component Handlers

    private void RadioAnimateMoveAbsolute_CheckedChanged(object sender, EventArgs e)
        {
        
        if (RadioAnimateMoveAbsolute.Checked) LabelAnimateMoveWhere.Text = "To";
        }

    private void RadioAnimateMoveRelative_CheckedChanged(object sender, EventArgs e)
        {
        
        if (RadioAnimateMoveRelative.Checked) LabelAnimateMoveWhere.Text = "By";
        }

    private void ButtonAnimateMove_Click(object sender, EventArgs e)
        {
        animateMove();

        updateScreen();
        }
        
    private void RadioAnimateTurnAbsolute_CheckedChanged(object sender,EventArgs e)
        {
        
        if (RadioAnimateTurnAbsolute.Checked) LabelAnimateTurnWhere.Text = "To";
        }

    private void RadioAnimateTurnRelative_CheckedChanged(object sender,EventArgs e)
        {
        
        if (RadioAnimateTurnRelative.Checked) LabelAnimateTurnWhere.Text = "By";
        }

    private void ButtonAnimateTurn_Click(object sender, EventArgs e)
        {
        animateTurn();

        updateScreen();
        }

    // Methods

    private void animateMove()
        {
        try {
            String key = BoxAnimateMoveId.Text;
            Single x = Convert.ToSingle(BoxAnimateMoveX.Text);
            Single y = Convert.ToSingle(BoxAnimateMoveY.Text);
            Single z = Convert.ToSingle(BoxAnimateMoveZ.Text);
            
            if (RadioAnimateMoveAbsolute.Checked || RadioAnimateMoveRelative.Checked)
               {
               bool success = false;
               
               if (RadioAnimateMoveAbsolute.Checked) { success = world.MoveTo(key,new Position(x,y,z)); }
               if (RadioAnimateMoveRelative.Checked) { success = world.MoveBy(key,new VectorC(x,y,z)); }
               
               if (success) Console = " * Actor movement succesful.";
               else Console = " * Actor movement failure. ID not found.";
               }
               
            else { Console = " * Input error. Choose absolute or relative coordinates.";  }
            }
        
        catch { Console = " * Input error. Incorrect coordinates."; }
        }

    private void animateTurn()
        {
        try {
            String key = BoxAnimateTurnId.Text;
            Single x = Convert.ToSingle(BoxAnimateTurnX.Text);
            Single y = Convert.ToSingle(BoxAnimateTurnY.Text);
            Single z = Convert.ToSingle(BoxAnimateTurnZ.Text);
            
            if (RadioAnimateTurnAbsolute.Checked || RadioAnimateTurnRelative.Checked)
               {
               bool success = false;
               
               if (RadioAnimateTurnAbsolute.Checked) { success = world.TurnTo(key,new Framework.Orientation(x,y,z)); }
               if (RadioAnimateTurnRelative.Checked) { success = world.TurnBy(key,new Framework.Orientation(x,y,z)); }
               
               if (success) Console = " * Actor rotation succesful.";
               else Console = " * Actor rotation failure. ID not found.";
               }
               
            else { Console = " * Input error. Choose absolute or relative angles.";  }
            }
        
        catch { Console = " * Input error. Incorrect angles."; }
        }

    #endregion
    
    #region Text Editor

    // Component Handlers

    // Methods

    #endregion

    #region Texture Editor

    // Component Handlers

    // Methods

    #endregion

    #region Sound Editor

    // Component Handlers

    // Methods

    #endregion

    }


}
